package com.atguigu.gmall.rabbitmq.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbitmq.config.RabbitConst;
import com.atguigu.gmall.rabbitmq.pojo.GmallCorrelationData;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Date;
import java.util.UUID;

/**
 * @author: Mamba
 * @version: 1.0
 * @Time: 2021/1/11 17:01
 * @Description:
 *      提供 MQ发消息    普通  延迟消息
 */
@Component
@SuppressWarnings("all")
public class RabbitService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;//信道   回调机制  交换机应答 队列应答



    //发普通消息   简单模式 工作模式  发布、订阅  路由模式（Routingkey) 主题
   public void sendMessage(String exchange,String routingkey,Object message){
       //子对象  消息丢失 回调下面这个对象进行重新发送
       GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
       //ID  UUID
       String uuid = UUID.randomUUID().toString();
       gmallCorrelationData.setId(uuid);
       //交换机
       gmallCorrelationData.setExchange(exchange);
       gmallCorrelationData.setRoutingKey(routingkey);
       gmallCorrelationData.setMessage(message);

       //在此将发送  Redis中
       // Map  rabbit:message = new HashMap();
       //rabbit:message.put(k,v)
       redisTemplate.opsForHash().put("rabbit:message",uuid,
               JSONObject.toJSONString(gmallCorrelationData));
       //发消息
       rabbitTemplate.convertAndSend(exchange,routingkey,message,gmallCorrelationData);
   }

    //发延迟消息 （基于死信的）
    public void sendDeadLetterMessage(String exchange,String routingkey,Object msg,int delayTime){
       //
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID UUID
        String uuid = UUID.randomUUID().toString();
        gmallCorrelationData.setId(uuid);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        gmallCorrelationData.setRoutingKey(routingkey);
        gmallCorrelationData.setMessage(msg);
        //是否是延迟消息
        gmallCorrelationData.setDelay(true);
        //延迟时间
        gmallCorrelationData.setDelayTime(delayTime);
        //放入缓存中
        redisTemplate.opsForHash().put("rabbit:message",uuid,JSONObject.toJSONString(gmallCorrelationData));
        //发延迟消息
        rabbitTemplate.convertAndSend(exchange,routingkey,msg,message -> {
            //延迟时间
            // setExpiration : 死信过期转发       单位是毫秒    2*60*60
            message.getMessageProperties().setExpiration(String.valueOf(delayTime*1000));
            System.out.println("发送时间:"+new Date());
            return message;
        },gmallCorrelationData);
    }

    //发延迟消息 （基于插件的 ）
    public void sendDelayMessage(String exchange,String routingKey,Object msg
            ,int delayTime) {
        //子对象  消息丢失 回调下面这个对象进行重新发送
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID UUID
        String uuid = UUID.randomUUID().toString();
        gmallCorrelationData.setId(uuid);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        gmallCorrelationData.setRoutingKey(routingKey);
        gmallCorrelationData.setMessage(msg);
        //是否是延迟消息
        gmallCorrelationData.setDelay(true);
        //延迟时间
        gmallCorrelationData.setDelayTime(delayTime);
        redisTemplate.opsForHash().put("rabbit:message",uuid,JSONObject.toJSONString(gmallCorrelationData));
        //发延迟消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //延迟时间
            //setDelay: 延迟插件
            message.getMessageProperties().setDelay(delayTime*1000);
            System.out.println("发送时间:"+new Date());
            return message;
        },gmallCorrelationData);
    }


}
